package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import com.zzyl.constant.SuperConstant;
import com.zzyl.dto.ResourceDto;
import com.zzyl.entity.Resource;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.ResourceMapper;
import com.zzyl.service.ResourceService;
import com.zzyl.utils.EmptyUtil;
import com.zzyl.utils.NoProcessing;
import com.zzyl.vo.ResourceVo;
import com.zzyl.vo.TreeItemVo;
import com.zzyl.vo.TreeVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

/**
 * @Description ResourceServiceImpl
 * @Author Lwj
 * @Date 2024-09-01-15:34
 */
@Service
public class ResourceServiceImpl implements ResourceService {
    @Autowired
    private ResourceMapper resourceMapper;

    /**
     * 资源列表
     *
     * @param resourceDto
     * @return
     */
    @Override
    public List<ResourceVo> findResourceList(ResourceDto resourceDto) {
        List<Resource> resources = resourceMapper.selectList(resourceDto);
        return BeanUtil.copyToList(resources, ResourceVo.class);
    }

    /**
     * 资源树形
     *
     * @param resourceDto
     * @return
     */
    @Override
    public TreeVo resourceTreeVo(ResourceDto resourceDto) {
        //1.构建查询条件
        ResourceDto dto = ResourceDto.builder().dataState(SuperConstant.DATA_STATE_0)
                .parentResourceNo(NoProcessing.processString(SuperConstant.ROOT_PARENT_ID))
                .resourceType(SuperConstant.MENU)
                .build();
        //2.查询所有资源数据
        List<Resource> resourcesList = resourceMapper.selectList(dto);
        if (EmptyUtil.isNullOrEmpty(resourcesList)) {
            throw new RuntimeException("资源信息未定义");
        }
        //3.定义返回的树形集合
        ArrayList<TreeItemVo> itemVos = new ArrayList<>();
        //4.使用hutool工具获取树形结构工具
        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
        //自定义名称由原有的name改成label
        treeNodeConfig.setNameKey("label");
        //利用hutool中的树形菜单功能实现
        List<Tree<String>> treeList = TreeUtil.build(resourcesList, SuperConstant.ROOT_PARENT_ID, treeNodeConfig,
                (resource, treeNode) -> {
                    treeNode.setName(resource.getResourceName());
                    treeNode.setId(resource.getResourceNo());
                    treeNode.setParentId(resource.getParentResourceNo());
                });
        //5.集合泛型转换
        List<TreeItemVo> children = BeanUtil.copyToList(treeList, TreeItemVo.class);
        //6.由于没有根节点，构建跟节点信息
        TreeItemVo itemVo = TreeItemVo.builder().id(SuperConstant.ROOT_PARENT_ID).label("智慧养老院").children(children).build();
        //7.封装到树形集合中
        itemVos.add(itemVo);
        //数据返回
        return TreeVo.builder().items(itemVos).build();
    }

    /**
     * 添加部门
     *
     * @param resourceDto
     */
    @Override
    public void createResource(ResourceDto resourceDto) {
        //类型转换拷贝
        Resource resource = BeanUtil.toBean(resourceDto, Resource.class);
        //1、查询父资源状态同步到子资源里面
        Resource parentResourceNo = resourceMapper.selectByParentResourceNo(resourceDto.getParentResourceNo());
        resource.setDataState(parentResourceNo.getDataState());
        //2、生成子资源编号
        String resourceNo = createResourceNo(resource);
        //封装子资源元编号
        resource.setResourceNo(resourceNo);
        //4、添加到数据库
        resourceMapper.insert(resource);

    }

    /**
     * 资源修改
     *
     * @param resourceDto
     */
    @Override
    public void reSetresource(ResourceDto resourceDto) {
        //类型转换拷贝
        Resource resource = BeanUtil.toBean(resourceDto, Resource.class);
        resourceMapper.update(resource);
    }

    /**
     * 启用禁用
     *
     * @param resourceDto
     */
    @Override
    public void ResetStatus(ResourceDto resourceDto) {
        // 类型转换拷贝
        Resource resource = BeanUtil.toBean(resourceDto, Resource.class);

        // 判断要禁用的菜单是否有子菜单
        ResourceDto dto = ResourceDto.builder().parentResourceNo(resource.getResourceNo()).build();
        List<Resource> resourcesList = resourceMapper.selectList(dto);

        // 菜单已分配，不允许禁用
        if (!EmptyUtil.isNullOrEmpty(resourcesList)) {
            for (Resource r : resourcesList) {
                if (r.getDataState().equals(SuperConstant.DATA_STATE_0)) {
                    throw new BaseException(BasicEnum.MENU_DISTRIBUTED);
                }
            }
        }
        // 查找父菜单
        List<Resource> parentResource = resourceMapper.selectParent(resource.getParentResourceNo());

        // 如果存在父菜单且父菜单为禁用状态，不允许启用
        if (EmptyUtil.isNullOrEmpty(resourcesList) && !EmptyUtil.isNullOrEmpty(parentResource)) {
            for (Resource r : parentResource) {
                if (r.getDataState().equals(SuperConstant.DATA_STATE_1)) {
                    throw new BaseException(BasicEnum.PARENT_MENU_DISABLE);
                }
            }
        }

        resourceMapper.updateState(resource);

    }

    /**
     * 删除资源菜单
     *
     * @param menuId
     */
    @Override
    public void deleteResource(String menuId) {
        ResourceDto resourceDto = new ResourceDto();
        resourceDto.setParentResourceNo(menuId);
        //查询要删除的菜单是否有子菜单
        List<Resource> resourcesList = resourceMapper.selectList(resourceDto);
        if (!EmptyUtil.isNullOrEmpty(resourcesList)) {
            //有子菜单
            throw new RuntimeException("该菜单有子菜单,不能删除");
        }
        resourceMapper.delete(resourceDto);
    }


    /**
     * 根据用户id查询对应的资源数据
     *
     * @param
     * @return
     *//*
    @Override
    public List<MenuVo> menus() {
        //1.获取登录人信息
        Long userId = UserThreadLocal.getMgtUserId();

        //2.根据用户id查询资源数据，调用mapper
        List<MenuVo> menuVoList = resourceMapper.findListByUserId(userId);

        //3.使用hutool工具实现树形结构
        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
        treeNodeConfig.setIdKey("resourceNo");
        treeNodeConfig.setParentIdKey("parentResourceNo");

        List<Tree<String>> treeList = TreeUtil.build(menuVoList, SuperConstant.ROOT_PARENT_ID, treeNodeConfig, (menus, tree) -> {
            tree.setId(menus.getResourceNo());
            tree.setName(menus.getName());
            tree.setParentId(menus.getParentResourceNo());

            //自定义属性
            tree.putExtra("path", menus.getPath());
            tree.putExtra("redirect", "/" + menus.getName());
            tree.putExtra("meta", new MenuMetaVo(menus.getName(), "", null));
        });

        //转化类型
        List<MenuVo> menuVos = BeanUtil.copyToList(treeList, MenuVo.class);

        //4.返回数据
        return menuVos;
    }*/

    /**
     * 生成子资源编号
     *
     * @param resource
     * @return
     */
    private String createResourceNo(Resource resource) {
        //1、如果是菜单，以及父资源编号是否大于三级
        if (resource.getResourceType().equals("m")
                && NoProcessing.processString(resource.getParentResourceNo()).length() / 3 >= 5) {
            throw new BaseException(BasicEnum.RESOURCE_DEPTH_UPPER_LIMIT);
        }
        //2.不大于三级，查询父资源编号下是否包含子资源,要先查询出所有的父资源list
        ResourceDto dto = ResourceDto.builder().parentResourceNo(resource.getParentResourceNo()).build();
        List<Resource> resourcesList = resourceMapper.selectList(dto);
        if (EmptyUtil.isNullOrEmpty(resourcesList)) {
            //3.父资源编号下没有下属节点，则新增  100 001 001 001 000--->新增下属节点100 001 001 001 001
            return NoProcessing.createNo(resource.getParentResourceNo(), false);
        } else {
            //4.有下属节点，则在原有基础上追加 100 001 001 001 001--->追加之后，100 001 001 001 002
            //要先获取下属节点中的最大值
            Long maxNo = resourcesList.stream().map(resource1 -> {
                return Long.valueOf(resource1.getResourceNo());
            }).max(Comparator.comparing(Long::intValue)).get();
            return NoProcessing.createNo(String.valueOf(maxNo), true);
        }
    }
}
